package server

import (
	"context"
	"embed"
	"fmt"
	"io/fs"
	"lan-file-transfer/core"
	"lan-file-transfer/models"
	"lan-file-transfer/server/middleware"
	"net/http"
	"sync"
	"time"

	"github.com/gin-gonic/gin"
)

// Server HTTP服务器
type Server struct {
	engine         *gin.Engine
	httpServer     *http.Server
	port           int
	state          models.ServerState
	stateMu        sync.RWMutex
	fileManager    *core.FileManager
	securityMgr    *core.SecurityManager
	configMgr      *core.ConfigManager
	semaphore      *core.Semaphore
	progressChans  sync.Map   // key: connectionID, value: chan models.DownloadProgress
	webFS          *embed.FS  // Web文件系统
	tlsEnabled     bool       // 是否启用TLS
	certPath       string     // 证书路径
	keyPath        string     // 私钥路径
}

// NewServer 创建服务器
func NewServer(
	fileManager *core.FileManager,
	securityMgr *core.SecurityManager,
	configMgr *core.ConfigManager,
	webFS *embed.FS,
	tlsEnabled bool,
	certPath, keyPath string,
) *Server {
	gin.SetMode(gin.ReleaseMode)

	return &Server{
		engine:        gin.New(),
		port:          configMgr.GetConfig().Port,
		state:         models.StateStopped,
		fileManager:   fileManager,
		securityMgr:   securityMgr,
		configMgr:     configMgr,
		semaphore:     core.NewSemaphore(configMgr.GetConfig().MaxConcurrent),
		webFS:         webFS,
		tlsEnabled:    tlsEnabled,
		certPath:      certPath,
		keyPath:       keyPath,
	}
}

// GetState 获取服务器状态
func (s *Server) GetState() models.ServerState {
	s.stateMu.RLock()
	defer s.stateMu.RUnlock()
	return s.state
}

// setState 设置服务器状态
func (s *Server) setState(state models.ServerState) {
	s.stateMu.Lock()
	defer s.stateMu.Unlock()
	s.state = state
}

// Start 启动服务器
func (s *Server) Start() error {
	s.setState(models.StateStarting)

	// 检查端口可用性
	if !core.IsPortAvailable(s.port) {
		s.port = core.FindAvailablePort(s.port)
		s.configMgr.SetPort(s.port)
	}

	// 重新创建engine(避免路由冲突)
	gin.SetMode(gin.ReleaseMode)
	s.engine = gin.New()

	// 设置中间件
	s.engine.Use(gin.Recovery())
	s.engine.Use(middleware.CORS())
	s.engine.Use(middleware.RateLimit())
	s.engine.Use(middleware.IPWhitelist())

	// 设置路由
	s.setupRoutes()

	// 创建HTTP服务器
	s.httpServer = &http.Server{
		Addr:         fmt.Sprintf(":%d", s.port),
		Handler:      s.engine,
		ReadTimeout:  30 * time.Second,
		WriteTimeout: 0, // 禁用写超时，支持大文件下载
		IdleTimeout:  120 * time.Second,
	}

	// 在goroutine中启动服务器
	go func() {
		var err error
		// 检查是否启用TLS
		if s.tlsEnabled && s.certPath != "" && s.keyPath != "" {
			// 启动HTTPS服务器
			err = s.httpServer.ListenAndServeTLS(s.certPath, s.keyPath)
		} else {
			// 启动HTTP服务器（降级模式）
			err = s.httpServer.ListenAndServe()
		}

		if err != nil && err != http.ErrServerClosed {
			s.setState(models.StateStopped)
		}
	}()

	s.setState(models.StateRunning)
	return nil
}

// Stop 停止服务器
func (s *Server) Stop() error {
	s.setState(models.StateStopping)

	if s.httpServer != nil {
		ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
		defer cancel()

		if err := s.httpServer.Shutdown(ctx); err != nil {
			return err
		}

		// 清理 httpServer 引用，确保下次启动时创建新实例
		s.httpServer = nil
	}

	s.setState(models.StateStopped)
	return nil
}

// GetPort 获取端口
func (s *Server) GetPort() int {
	return s.port
}

// setupRoutes 设置路由
func (s *Server) setupRoutes() {
	// 静态文件服务(Web界面)
	webStatic, _ := fs.Sub(*s.webFS, "web")
	s.engine.StaticFS("/static", http.FS(webStatic))

	// 首页
	s.engine.GET("/", func(c *gin.Context) {
		data, _ := s.webFS.ReadFile("web/index.html")
		c.Data(http.StatusOK, "text/html; charset=utf-8", data)
	})

	// API路由(需要在api包中实现具体handler)
	api := s.engine.Group("/api")
	{
		// 认证相关(不需要token)
		api.POST("/auth", s.handleAuth)

		// 需要认证的路由
		authenticated := api.Group("")
		authenticated.Use(middleware.AuthMiddleware())
		{
			authenticated.GET("/files", s.handleGetFiles)
			authenticated.GET("/filter-rules", s.handleGetFilterRules)
			authenticated.GET("/download/:id", s.handleDownload)
			authenticated.POST("/download/batch", s.handleBatchDownload)
		}
	}

	// WebSocket路由
	s.engine.GET("/ws/progress", s.handleWebSocket)
}

// GetFileManager 获取文件管理器
func (s *Server) GetFileManager() *core.FileManager {
	return s.fileManager
}

// GetSecurityManager 获取安全管理器
func (s *Server) GetSecurityManager() *core.SecurityManager {
	return s.securityMgr
}

// GetSemaphore 获取信号量
func (s *Server) GetSemaphore() *core.Semaphore {
	return s.semaphore
}

// IsTLSEnabled 返回是否启用TLS
func (s *Server) IsTLSEnabled() bool {
	return s.tlsEnabled
}
